package drds.plus.sql_process.abstract_syntax_tree.configuration;

import java.util.*;

/**
 * 一个table的描述，包含主键信息/字段信息/索引信息
 */
public class TableMetaData implements Cloneable {
    /**
     * 表名
     */
    private final String tableName;
    /**
     * orderByColumnMetaDataList(主要用于排序)
     */
    private final List<ColumnMetaData> orderByColumnMetaDataList = new LinkedList<ColumnMetaData>();
    /**
     * 主键索引描述
     */
    private final Map<String/* indexName */, IndexMapping> primaryKeyIndexNameToIndexMetaDataMap = new HashMap<String, IndexMapping>(4);
    /**
     * 二级索引描述
     */
    private final Map<String/* index Name */, IndexMapping> secondaryIndexNameToIndexMetaDataMap = new HashMap<String, IndexMapping>(8);

    private final Map<String, ColumnMetaData> primaryKeyKeyColumnNameToColumnMetaDataMap = new HashMap<String, ColumnMetaData>();
    private final Map<String, ColumnMetaData> primaryKeyValueColumnNameToColumnMetaDataMap = new HashMap<String, ColumnMetaData>();
    private final Map<String, ColumnMetaData> allColumnNameToColumnMetaDataMap = new HashMap<String, ColumnMetaData>();

    private boolean temporaryTable = false;
    private boolean sortedDuplicates = true;

    public TableMetaData(String tableName, List<ColumnMetaData> orderByColumnMetaDataList, IndexMapping primaryKeyIndexMapping, List<IndexMapping> secondaryIndexNameToIndexMappingMap) {
        this.tableName = tableName;
        this.orderByColumnMetaDataList.addAll(orderByColumnMetaDataList);
        if (primaryKeyIndexMapping != null) {
            this.primaryKeyIndexNameToIndexMetaDataMap.put(primaryKeyIndexMapping.getIndexName(), primaryKeyIndexMapping);
            for (ColumnMetaData columnMetaData : primaryKeyIndexMapping.getKeyColumnMetaDataList()) {
                this.primaryKeyKeyColumnNameToColumnMetaDataMap.put(columnMetaData.getColumnName(), columnMetaData);
                this.allColumnNameToColumnMetaDataMap.put(columnMetaData.getColumnName(), columnMetaData);
            }
            for (ColumnMetaData columnMetaData : primaryKeyIndexMapping.getValueColumnMetaDataList()) {
                this.primaryKeyValueColumnNameToColumnMetaDataMap.put(columnMetaData.getColumnName(), columnMetaData);
                this.allColumnNameToColumnMetaDataMap.put(columnMetaData.getColumnName(), columnMetaData);
            }
        }
        if (secondaryIndexNameToIndexMappingMap != null) {
            for (IndexMapping indexMapping : secondaryIndexNameToIndexMappingMap) {
                this.secondaryIndexNameToIndexMetaDataMap.put(indexMapping.getIndexName(), indexMapping);
            }
        }

    }

    public IndexMapping getPrimaryKeyIndexMetaData() {
        return primaryKeyIndexNameToIndexMetaDataMap.isEmpty() ? null : primaryKeyIndexNameToIndexMetaDataMap.values().iterator().next();
    }

    public List<IndexMapping> getSecondaryIndexNameToIndexMetaDataMapValues() {
        return new ArrayList(secondaryIndexNameToIndexMetaDataMap.values());
    }

    public Map<String, IndexMapping> getSecondaryIndexNameToIndexMetaDataMap() {
        return secondaryIndexNameToIndexMetaDataMap;
    }

    public String getTableName() {
        return tableName;
    }

    public Collection<ColumnMetaData> getPrimaryKeyKeyColumnNameToColumnMetaDataMapValues() {
        return primaryKeyKeyColumnNameToColumnMetaDataMap.values();
    }

    public Collection<ColumnMetaData> getPrimaryKeyValueColumnNameToColumnMetaDataMapValues() {
        return primaryKeyValueColumnNameToColumnMetaDataMap.values();
    }

    public Map<String, ColumnMetaData> getPrimaryKeyKeyColumnNameToColumnMetaDataMap() {
        return this.primaryKeyKeyColumnNameToColumnMetaDataMap;
    }

    public List<ColumnMetaData> getOrderByColumnMetaDataList() {
        return orderByColumnMetaDataList;
    }

    public IndexMapping getIndexMetaData(String indexName) {
        IndexMapping indexMapping = primaryKeyIndexNameToIndexMetaDataMap.get(indexName);
        if (indexMapping != null) {
            return indexMapping;
        }
        indexMapping = secondaryIndexNameToIndexMetaDataMap.get(indexName);
        return indexMapping;
    }

    public List<IndexMapping> getIndexMetaDataList() {
        List<IndexMapping> indexMappingList = new ArrayList<IndexMapping>();
        IndexMapping primaryIndexMapping = this.getPrimaryKeyIndexMetaData();
        if (primaryIndexMapping != null) {
            indexMappingList.add(this.getPrimaryKeyIndexMetaData());
        }
        indexMappingList.addAll(this.getSecondaryIndexNameToIndexMetaDataMapValues());
        return indexMappingList;
    }

    public ColumnMetaData getColumnMetaData(String name) {
        if (name.contains(".")) {
            return allColumnNameToColumnMetaDataMap.get(name.split("\\.")[1]); // 避免转义
        }
        return allColumnNameToColumnMetaDataMap.get(name);
    }

    public boolean isTemporaryTable() {
        return this.temporaryTable;
    }

    public void setTemporaryTable(boolean temporaryTable) {
        this.temporaryTable = temporaryTable;
    }

    public boolean isSortedDuplicates() {
        return sortedDuplicates;
    }

    public void setSortedDuplicates(boolean sortedDuplicates) {
        this.sortedDuplicates = sortedDuplicates;

    }
}
